<?php
/**
 * 格式化函数库.
 * 
 * 
 * 其中有部分函数来源于第三方开源库.如wordpress等.
 * 
 * @author Leo Ning <leo.ning@like18.com>
 * @copyright LIKE18 INC. 2008 - 2011
 * @version 1.0
 * @since 1.0
 * @package utils
 * @subpackage functions
 */
/**
 * Navigates through an array and removes slashes from the values.
 *
 * If an array is passed, the array_map() function causes a callback to pass the
 * value back to the function. The slashes from this value will removed.
 *
 *
 * @param array|string $value The array or string to be striped.
 * @return array|string Stripped array (or string in the callback).
 */
function stripslashes_deep($value) {
	if (is_array ( $value )) {
		$value = array_map ( 'stripslashes_deep', $value );
	} elseif (is_object ( $value )) {
		$vars = get_object_vars ( $value );
		foreach ( $vars as $key => $data ) {
			$value->{$key} = stripslashes_deep ( $data );
		}
	} else {
		$value = stripslashes ( $value );
	}
	
	return $value;
}
/**
 * Checks for invalid UTF8 in a string.
 *
 *
 * @param string $string The text which is to be checked.
 * @param boolean $strip Optional. Whether to attempt to strip out invalid UTF8. Default is false.
 * @return string The checked text.
 */
function wp_check_invalid_utf8($string, $strip = false) {
	$string = ( string ) $string;
	
	if (0 === strlen ( $string )) {
		return '';
	}
	
	// Store the site charset as a static to avoid multiple calls to get_option()
	static $is_utf8 = true;
	//if ( !isset( $is_utf8 ) ) {
	//	$is_utf8 = in_array( get_option( 'blog_charset' ), array( 'utf8', 'utf-8', 'UTF8', 'UTF-8' ) );
	//}
	if (! $is_utf8) {
		return $string;
	}
	
	// Check for support for utf8 in the installed PCRE library once and store the result in a static
	static $utf8_pcre = null;
	if (is_null($utf8_pcre)) {
		$utf8_pcre = @preg_match ( '/^./u', 'a' );
	}
	// We can't demand utf8 in the PCRE installation, so just return the string in those cases
	if (! $utf8_pcre) {
		return $string;
	}
	
	// preg_match fails when it encounters invalid UTF8 in $string
	if (1 === @preg_match ( '/^./us', $string )) {
		return $string;
	}
	
	// Attempt to strip the bad chars if requested (not recommended)
	if ($strip && function_exists ( 'iconv' )) {
		return iconv ( 'utf-8', 'utf-8', $string );
	}
	
	return '';
}

function _wp_specialchars($string, $quote_style = ENT_NOQUOTES, $charset = 'utf8') {
	$string = ( string ) $string;
	if (0 === strlen ( $string )) {
		return '';
	}
	// Don't bother if there are no specialchars - saves some processing
	if (! preg_match ( '/[&<>"\']/', $string )) {
		return $string;
	}
	// Account for the previous behaviour of the function when the $quote_style is not an accepted value
	if (empty ( $quote_style )) {
		$quote_style = ENT_NOQUOTES;
	} elseif (! in_array ( $quote_style, array (0, 2, 3, 'single', 'double' ), true )) {
		$quote_style = ENT_QUOTES;
	}
	if (in_array ( $charset, array ('utf8', 'utf-8', 'UTF8' ) )) {
		$charset = 'UTF-8';
	}
	$_quote_style = $quote_style;
	if ($quote_style === 'double') {
		$quote_style = ENT_COMPAT;
		$_quote_style = ENT_COMPAT;
	} elseif ($quote_style === 'single') {
		$quote_style = ENT_NOQUOTES;
	}
	$string = @htmlspecialchars ( $string, $quote_style, $charset );
	// Backwards compatibility
	if ('single' === $_quote_style) {
		$string = str_replace ( "'", '&#039;', $string );
	}
	return $string;
}

/**
 * Convert entities, while preserving already-encoded entities.
 *
 * @link http://www.php.net/htmlentities Borrowed from the PHP Manual user notes.
 *
 *
 * @param string $myHTML The text to be converted.
 * @return string Converted text.
 */
function htmlentities2($myHTML) {
	$translation_table = get_html_translation_table ( HTML_ENTITIES, ENT_QUOTES );
	$translation_table [chr ( 38 )] = '&';
	return preg_replace ( '/&(?![A-Za-z]{0,4}\w{2,3};|#[0-9]{2,3};)/', "&amp;", strtr ( $myHTML, $translation_table ) );
}
/**
 * Escaping for HTML blocks.
 *
 *
 * @param string $text
 * @return string
 */
function esc_html($text) {
	$safe_text = wp_check_invalid_utf8 ( $text );
	$safe_text = _wp_specialchars ( $safe_text, ENT_QUOTES );
	return apply_filter ( 'esc_html', $safe_text, $text );
}
/**
 * Escaping for HTML attributes.
 *
 *
 * @param string $text
 * @return string
 */
function esc_attr($text) {
	$safe_text = wp_check_invalid_utf8 ( $text );
	$safe_text = _wp_specialchars ( $safe_text, ENT_QUOTES );
	return apply_filter ( 'attribute_escape', $safe_text, $text );
}
/**
 * Parses a string into variables to be stored in an array.
 *
 * Uses {@link http://www.php.net/parse_str parse_str()} and stripslashes if
 * {@link http://www.php.net/magic_quotes magic_quotes_gpc} is on.
 *
 * @since 2.2.1
 * @uses apply_filter() for the 'wp_parse_str' filter.
 *
 * @param string $string The string to be parsed.
 * @param array $array Variables will be stored in this array.
 */
function wp_parse_str($string, &$array) {
	parse_str ( $string, $array );
	if (get_magic_quotes_gpc ())
		$array = stripslashes_deep ( $array );
	$array = apply_filter ( 'wp_parse_str', $array );
}
/**
 * Unserialize value only if it was serialized.
 *
 * @see wordpress 
 *
 * @param string $original Maybe unserialized original, if is needed.
 * @return mixed Unserialized data can be any type.
 */
function maybe_unserialize($original) {
	if (is_serialized ( $original )) // don't attempt to unserialize data that wasn't serialized going in
		return @unserialize ( $original );
	return $original;
}
/**
 * Serialize data, if needed.
 *
 * @see wordpress 
 *
 * @param mixed $data Data that might be serialized.
 * @return mixed A scalar data
 */
function maybe_serialize($data) {
	if (is_array ( $data ) || is_object ( $data ))
		return @serialize ( $data );
	
	if (is_serialized ( $data ))
		return @serialize ( $data );
	
	return $data;
}
/**
 * Check value to find if it was serialized.
 *
 * If $data is not an string, then returned value will always be false.
 * Serialized data is always a string.
 *
 * @see wordpress 
 *
 * @param mixed $data Value to check to see if was serialized.
 * @return bool False if not serialized and true if it was.
 */
function is_serialized($data) {
	// if it isn't a string, it isn't serialized
	if (! is_string ( $data ))
		return false;
	$data = trim ( $data );
	if ('N;' == $data)
		return true;
	if (! preg_match ( '/^([adObis]):/', $data, $badions ))
		return false;
	switch ($badions [1]) {
		case 'a' :
		case 'O' :
		case 's' :
			if (preg_match ( "/^{$badions[1]}:[0-9]+:.*[;}]\$/s", $data ))
				return true;
			break;
		case 'b' :
		case 'i' :
		case 'd' :
			if (preg_match ( "/^{$badions[1]}:[0-9.E-]+;\$/", $data ))
				return true;
			break;
	}
	return false;
}
/**
 * 生成树形选择列表项
 * @param string $text 显示字符
 * @param int $tab 显示级别
 * @return string
 */
function trees($text, $tab = 0) {
	if ($tab == 0) {
		return $text;
	} else if ($tab == 1) {
		return "├─&nbsp;" . $text;
	} else {
		$trees = array ();
		for($i = 0; $i < $tab - 1; $i ++) {
			$trees [$i] = '&nbsp;&nbsp;&nbsp;&nbsp;';
		}
		$trees [$tab - 1] = '├─&nbsp;' . $text;
		return join ( "", $trees );
	}
}
/**
 * 输出args到函数的参数
 * 
 * 格式化Smarty模板中的参数,将
 * <p>
 * "'$_smarty_tpl->getVariable(\'name\')->value[\'a\']'"
 * </p>
 * 格式化为
 * <p>
 *  "$_smarty_tpl->getVariable('name')->value['a']"
 * </p>
 * 
 * @param array $args smarty args
 * @return string 格式化后的参数字符
 */
function smarty_out_args($args) {
	$args = var_export ( $args, true );
	//"'$_smarty_tpl->getVariable(\'name\')->value[\'a\']'" => "$_smarty_tpl->getVariable('name')->value['a']" 
	$args = preg_replace ( array ('/\'\$_smarty_tpl.*\(\\\\\'(.+)\\\\\'\)->value\'/', '/\'\$_smarty_tpl.*\(\\\\\'(.+)\\\\\'\)->value(\[\\\\\'(.+)\\\\\'\])?\'/', '/\\n/' ), array ('\$_smarty_tpl->getVariable(\'$1\')->value', '\$_smarty_tpl->getVariable(\'$1\')->value[\'$3\']', '' ), $args );
	return $args;
}